package com.wiken.orderservice.service.impl;

import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wiken.orderservice.entity.Order;
import com.wiken.orderservice.entity.OrderCommodity;
import com.wiken.orderservice.feign.StoreServiceClient;
import com.wiken.orderservice.feign.UserStoreActivityClient;
import com.wiken.orderservice.mapper.OrderMapper;
import com.wiken.orderservice.rocketMQ.OrderProducer;
import com.wiken.orderservice.service.IOrderService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wiken.orderservice.vo.OrderAndCommmodityVO;
import com.wiken.servicecommon.common.Code;
import com.wiken.servicecommon.common.PageUtill;
import com.wiken.servicecommon.common.TokenUtil;
import com.wiken.servicecommon.common.exception.DefaultException;
import io.jsonwebtoken.Claims;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.commons.util.IdUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author wiken
 * @since 2022-12-28
 */
@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements IOrderService {

    @Value("${properties.work_id}")
    private Long work_id;

    @Value("${properties.datacenter_id}")
    private Long datacenter_id;

    private String topic = "order";

    private String tags = "order_expire";

    @Autowired
    private OrderProducer orderProducer;

    @Autowired
    private OrderCommodityServiceImpl orderCommodityService;

    @Autowired
    private StoreServiceClient storeServiceClient;

    private String getUserIdByToken(String token) {
        //解析token，取出userId
        Claims claims = TokenUtil.parseToken(token);
        if(token == null) throw new DefaultException(Code.ERROR_AUTHORIZATION_NULL, "请重新登陆");

        String userId = claims.get("userId", String.class);

        if(userId == null) throw new DefaultException(Code.ERROR_AUTHORIZATION_EXPIRATION, "token已经过期");

        return userId;
    }

    @Override
    @Transactional
    public Order addOrder(Order order, List<OrderCommodity> orderCommodities, String token) {
        //TODO 添加优惠劵功能，如果用户使用了优惠劵，那么就进行相关业务操作
        String userId = getUserIdByToken(token);

        //为订单生成id（采用雪花算法）
        Snowflake snowflake = IdUtil.getSnowflake(work_id, datacenter_id);

        String orderId = snowflake.nextId()+"";
        System.out.println(orderId + " orderId");
        //订单userId为token中的userId
        order.setId(orderId);
        order.setUserId(userId);
        order.setStatus(1);

        int insert = baseMapper.insert(order);
        if(insert <= 0) return null;

        //检查orderCommodity中的amount是否被用户恶意修改
        List<OrderCommodity> orderCommodityList = orderCommodityService.getOrderCommodityListByCommodityList(orderCommodities);

        HashMap<String, OrderCommodity> orderCommodityHashMap = new HashMap<>();

        //使用优惠劵
        if(order.getUserStoreActivityId() != null){
            boolean useSuccess = storeServiceClient.useStoreActivity(order.getUserStoreActivityId(), token);

            if(!useSuccess) throw new DefaultException(Code.ERROR, "优惠劵使用失败");
        }

        for (OrderCommodity oc : orderCommodityList){
            orderCommodityHashMap.put(oc.getCommodityId(), oc);
        }

        //将数据库中的查询到的商品价格和用户购买的数量相乘
        for(OrderCommodity oc: orderCommodities){
            OrderCommodity orderCommodity = orderCommodityHashMap.get(oc.getCommodityId());

            BigDecimal amount =
                    orderCommodity.getPrice().multiply(
                            BigDecimal.valueOf( oc.getCommodityNumber())
                    );

            oc.setPrice(orderCommodity.getPrice());

            oc.setAmount(amount); //设置正确的余额

            oc.setOrderId(orderId); //设置这些订单商品的订单id
            oc.setStatus(0); //设置评价状态为待评价

            boolean success = orderCommodityService.addOrderCommodity(oc);

            if(!success) throw new DefaultException(Code.ERROR_ORDER_COMMODITY_INSERT, "添加商品到订单失败");
        }

        //如果订单30分钟未支付，该订单状态就会过期
        orderProducer.sendDelayMessage(topic, tags, orderId, 16);
        return order;
    }

    @Override
    public boolean delOrder(String orderId, String token) {
        //判断token是否存在和过期

        String userId = getUserIdByToken(token);

        Order order = baseMapper.selectOne(new QueryWrapper<Order>().eq("id", orderId));

        //如果token和操作的订单所属的用户不一致，抛出异常
        if(!order.getUserId().equals(userId)) new DefaultException(Code.ERROR_AUTHORIZATION, "操作异常");

        //将订单状态设置为0即为删除订单
        order.setStatus(0);

        baseMapper.updateById(order);

        return true;
    }

    @Override
    public boolean updateOrder(Order order, String token) {
        throw new DefaultException(Code.ERROR, "功能还没有实现");

//        return false;
    }


    void setTotalAmountOfOrder(Page<OrderAndCommmodityVO> orderAndCommmodityVOPage){
        for (OrderAndCommmodityVO record : orderAndCommmodityVOPage.getRecords()) {
            BigDecimal totalAmount = new BigDecimal(0);
            for (OrderCommodity orderCommodity : record.getOrderCommodityList()) {
                totalAmount = totalAmount.add(orderCommodity.getAmount());
            }

            record.setTotalAmount(totalAmount);
        }
    }

    @Override
    public Page<OrderAndCommmodityVO> getOrderOfPayed(String token, PageUtill pageUtill) {
        String userId = getUserIdByToken(token);

        Page page = new Page();
        page.setSize(pageUtill.getSize());
        page.setCurrent(pageUtill.getCurrent());

        Page<OrderAndCommmodityVO> orderList = baseMapper.getOrderOfPayed(userId, page);
        setTotalAmountOfOrder(orderList);
        return orderList;
    }


    @Override
    public Page<OrderAndCommmodityVO> getOrderOfPay(String token, PageUtill pageUtill) {
        String userId = getUserIdByToken(token);

        Page page = new Page();
        page.setSize(pageUtill.getSize());
        page.setCurrent(pageUtill.getCurrent());

        Page<OrderAndCommmodityVO> orderList = baseMapper.getOrderOfPay(userId, page);
        setTotalAmountOfOrder(orderList);
        return orderList;
    }

    @Override
    public Page<OrderAndCommmodityVO> getOrderOfExpire(String token, PageUtill pageUtill) {
        String userId = getUserIdByToken(token);

        Page page = new Page();
        page.setSize(pageUtill.getSize());
        page.setCurrent(pageUtill.getCurrent());

        Page<OrderAndCommmodityVO> orderList = baseMapper.getOrderOfExpire(userId, page);
        setTotalAmountOfOrder(orderList);
        return orderList;
    }
}
